package com.animallife.android.db;

import java.util.HashMap;

import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;

import com.animallife.android.db.AnimalLifeDBSchema.Tables;
import com.animallife.android.model.Animals;
import com.animallife.android.ui.AnimalListActivity;
import com.animallife.android.util.Config;

public class AnimalLifeProvider extends ContentProvider {

	private static final UriMatcher sUriMatcher = buildUriMatcher();
	private static final int ANIMALS = 100;
	private static final int ANIMAL_SUGGEST_SEARCH = 101;
	public static final String KEY_WORD = SearchManager.SUGGEST_COLUMN_TEXT_1;
	private static final HashMap<String, String> mColumnMap = buildColumnMap();

	private static HashMap<String, String> buildColumnMap() {
		HashMap<String, String> map = new HashMap<String, String>();
		map.put(KEY_WORD, KEY_WORD);
		map.put(AnimalColumns._ID.getName(), "rowid AS " + AnimalColumns._ID.getName());
		map.put(AnimalColumns.ANIMAL_CLASS.getName(), AnimalColumns.ANIMAL_CLASS.getName());
		map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
		return map;
	}

	private static UriMatcher buildUriMatcher() {
		final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
		final String authority = AnimalLifeDBSchema.CONTENT_AUTHORITY;

		matcher.addURI(authority, Tables.ANIMALS, ANIMALS);
		matcher.addURI(authority, Tables.ANIMALS + "/*", ANIMALS);
		matcher.addURI(authority, "animal_search/" + SearchManager.SUGGEST_URI_PATH_QUERY, ANIMAL_SUGGEST_SEARCH);
		matcher.addURI(authority, "animal_search/" + SearchManager.SUGGEST_URI_PATH_QUERY + "/*", ANIMAL_SUGGEST_SEARCH);
		return matcher;
	}

	@Override
	public boolean onCreate() {
		return true;
	}

	@Override
	public String getType(Uri uri) {
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case ANIMALS:
			return Animals.CONTENT_TYPE;
		case ANIMAL_SUGGEST_SEARCH:
			return SearchManager.SUGGEST_MIME_TYPE;
		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		final SQLiteDatabase db = getWritableDatabase();
		final SelectionBuilder builder = buildSimpleSelection(uri);
		return builder.where(selection, selectionArgs).delete(db);
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		return uri;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		final SQLiteDatabase db = getReadableDatabase();

		final int match = sUriMatcher.match(uri);
		final SQLiteQueryBuilder builder = buildExpandedSelection(uri, match);

		switch (match) {
		case ANIMALS:

			break;
		case ANIMAL_SUGGEST_SEARCH:
			projection = new String[] { AnimalColumns._ID.getName(), AnimalColumns.NAME.getName(), AnimalColumns.ANIMAL_CLASS.getName(),
					SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID };
			builder.setProjectionMap(mColumnMap);
			selection = AnimalColumns.ANIMAL_CLASS + " = '" + AnimalListActivity.selectionArgs + "' and " + AnimalColumns.NAME.getName() + " like  '%"
					+ selectionArgs[0] + "%'";
			selectionArgs = null;
			sortOrder = AnimalColumns.NAME.getName();
			break;

		default:
			break;
		}

		return builder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
	}

	private SQLiteQueryBuilder buildExpandedSelection(Uri uri, int match) {
		final SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
		switch (match) {
		case ANIMALS: {
			builder.setTables(Tables.ANIMALS);
			break;
		}
		case ANIMAL_SUGGEST_SEARCH: {
			builder.setTables(Tables.ANIMALS);
			break;
		}

		default: {
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
		}
		return builder;
	}

	private SQLiteDatabase getReadableDatabase() {
		DatabaseController dbController = ServiceLocator.getInstance(getContext()).getService(DatabaseController.class);
		return dbController.getReadableDatabase();
	}

	private SQLiteDatabase getWritableDatabase() {
		DatabaseController dbController = ServiceLocator.getInstance(getContext()).getService(DatabaseController.class);
		return dbController.getWritableDatabase();
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

		Log.d(Config.LOG_TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
		final SQLiteDatabase db = getWritableDatabase();
		final SelectionBuilder builder = buildSimpleSelection(uri);
		return builder.where(selection, selectionArgs).update(db, values);

	}

	private SelectionBuilder buildSimpleSelection(Uri uri) {
		final SelectionBuilder builder = new SelectionBuilder();
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case ANIMALS: {
			return builder.table(Tables.ANIMALS);
		}

		default:
			throw new UnsupportedOperationException("Unknown uri: " + uri);

		}
	}

}
